﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Cambaz
{
  /// <summary>
  /// Bir kelimenin en küçük birimini tüm özellikleriyle temsil eden eden içsel, mühürlü sınıf.
  /// </summary>
  internal sealed class Yapi
  {
    public Yapi(char harf, bool kokBileseni, bool desen, bool zorunlu)
    {
      this.harf = harf;
      this.kokBileseni = kokBileseni;
      this.desen = desen;
      this.zorunlu = zorunlu;
    }

    private char harf;
    private bool kokBileseni;
    private bool desen;
    private bool zorunlu;

    private char[] sesliHarfler = { 'a', 'e', 'ı', 'i', 'o', 'ö', 'u', 'ü' };
    private char[] inceSesliHarfler = { 'e', 'i', 'ö', 'ü' };
    private char[] sertSessizHarfler = { 'f', 's', 't', 'k', 'ç', 'ş', 'h', 'p' };

    public char Harf
    {
      get { return harf; }
      set { harf = value; }
    }

    public bool Desen
    {
      get { return desen; }
    }

    public bool KokBileseni
    {
      get { return kokBileseni; }
    }

    public char[] DesenKarakterleri
    {
      get
      {
        List<char> karakterler = new List<char>();
        switch (this.harf)
        {
          case 'a':
            karakterler.Add('a');
            karakterler.Add('e');
            break;
          case 'ı':
            karakterler.Add('i');
            karakterler.Add('ı');
            karakterler.Add('u');
            karakterler.Add('ü');
            break;
          default:
            break;
        }
        return karakterler.ToArray();
      }
    }

    public bool Zorunlu
    {
      get { return zorunlu; }
    }

    public bool SesliHarf
    {
      get { return (Array.IndexOf(this.sesliHarfler, this.Harf) > -1); }
    }

    public bool InceSesliHarf
    {
      get { return (Array.IndexOf(this.inceSesliHarfler, this.Harf) > -1); }
    }

    public bool KalinSesliHarf
    {
      get { return this.SesliHarf && !this.InceSesliHarf; }
    }

    public bool SertSessizHarf
    {
      get { return (Array.IndexOf(this.sertSessizHarfler, this.Harf) > -1); }
    }

    public override string ToString()
    {
      return this.harf + " " + (this.Desen ? "Desen" : "Harf");
    }

    public static Yapi[] Olustur(string govde, string desen)
    {
      Regex regex = new Regex("(\\{(?<desenKarakter>[^\\}]+)\\})|(?<normalKarakter>\\w)");
      MatchCollection eslesmeler = null;

      List<Yapi> yapilar = new List<Yapi>();

      eslesmeler = regex.Matches(govde);
      foreach (Match eslesme in eslesmeler)
      {
        string normalKarakter = eslesme.Groups["normalKarakter"].Value;
        string desenKarakter = eslesme.Groups["desenKarakter"].Value;

        Yapi yapi = null;
        if (desenKarakter != string.Empty)
        {
          bool zorunluluk = !desenKarakter.Contains("(");

          char harf = Convert.ToChar(desenKarakter.Replace("(", string.Empty).Replace(")", string.Empty));
          yapi = new Yapi(harf, true, true, zorunluluk);
        }
        else
          yapi = new Yapi(Convert.ToChar(normalKarakter), true, false, true);
        yapilar.Add(yapi);
      }

      eslesmeler = regex.Matches(desen);
      foreach (Match eslesme in eslesmeler)
      {
        string normalKarakter = eslesme.Groups["normalKarakter"].Value;
        string desenKarakter = eslesme.Groups["desenKarakter"].Value;

        Yapi yapi = null;
        if (desenKarakter != string.Empty)
        {
          bool zorunluluk = !desenKarakter.Contains("(");

          char harf = Convert.ToChar(desenKarakter.Replace("(", string.Empty).Replace(")", string.Empty));
          yapi = new Yapi(harf, false, true, zorunluluk);
        }
        else
          yapi = new Yapi(Convert.ToChar(normalKarakter), false, false, true);
        yapilar.Add(yapi);
      }

      return yapilar.ToArray();
    }
  }
}